home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-22 | 60.6 KB | 1,341 lines |
-
- +-----------------------------------------+
- |+---------------------------------------+|
- || Dokumentation zur GEM-Force-Library ||
- |+---------------------------------------+|
- +-----------------------------------------+
-
-
- Inhaltsverzeichnis
- ==================
-
- 1 Vorwort
- 2 Das Modul-Konzept
- 3 Die Struktur der GEM-Force-Library
- 4 Modul GLOBAL
- 5 Modul WINDOWS
- 6 Modul TOS
-
-
- 1. Vorwort
- ==========
-
- Die Ihnen vorliegende GEM-Force-Library für Pure C ist ein Versuch, die oftmals
- langwierige GEM-Programmierung zu vereinfachen und Funktionen zur Verfügung zu
- stellen, die zwar kompakt und leistungsfähig sein sollen, jedoch den
- Programmierer in seiner Flexibilität nicht einschränken sollen. Aus diesem
- Grund wurde - im Gegensatz zu anderen verbreiteten Libraries - keine Funktion
- geschrieben, die die AES-Events empfängt (evnt_multi) und verarbeitet, ohne daß
- der Programmierer direkt Zugriff darauf hat; das wäre zwar in einigen Bereichen
- für den unerfahreneren Programmierer einfacher, schränkt aber auf der anderen
- Seite den erfahreneren Programmierer zu sehr ein.
- Ich hoffe Ihnen mit der GEM-Force-Library ein Instrument an die Hand zu geben,
- mit dem Sie (wenigstens mit Grundkenntnissen der GEM-Programmierung und
- natürlich C bewaffnet) einfacher GEM-Programme schreiben können. Dabei sollte
- es keine Rolle spielen, ob Sie fortgeschrittener Anfänger oder schon angehender
- Profi sind. In jedem Fall: Viel Erfolg !
- An dieser Stelle möchte ich noch den Brüdern Jürgen und Dieter Geiß, den
- Autoren des Buches "Vom Anfänger zum GEM-Profi", erschienen im Hüthig-Verlag,
- danken. Viele der in der Library enthaltenen Funktionen lehnen sich sehr eng an
- die von ihnen vorgestellten Funktionen an. Ohne ihr Einverständnis wäre diese
- Library in dieser Form nicht möglich gewesen. Also: Herzlichen Dank !
- GEM-Force wurde geschrieben von:
-
- René Rosendahl, Software-Entwicklung
- Kameruner Str. 107
- 32791 Lage
- Telefon 05232/78916 (ab 17.00 Uhr !)
- BLZ 476 501 30 (Sparkasse Detmold)
- Konto 176004000
-
- Bevor nun auf die eigentlichen Funktionen eingegangen wird, muß noch etwas
- grundlegendes erklärt werden, und zwar...
-
-
- 2. Das Modul-Konzept
- ====================
-
- Das in GEM-Force realisierte Modul-Konzept ist im Grunde das gleiche, das auch
- in dem Buch "Vom Anfänger zum GEM-Profi" von den Gebrüdern Geiß vorgestellt
- wurde. Es teilt Variablen und Funktionen in Bezug auf ihren Geltungsbereich in
- die Arten lokal und global bezogen auf das C-Modul ein, in dem diese definiert
- sind. Die lokalen Funktionen/Variablen sind modul-lokal, d. h. static, während
- die globalen in allen Modulen definiert sind.
- Die Vorgehensweise ist folgende:
- 1. Alle globalen Funktionen und Variablen werden mit "GLOBAL" gekennzeichnet
- und in ein Header-File für das jeweilige Modul geschrieben.
- 2. Die modul-lokalen Funktionen und Variablen werden mit "LOCAL" gekennzeichnet
- und im C-Source selber zu Beginn definiert.
- 3. Jedes Modul muß als erste Header-Datei die Datei "GFIMPORT.H" laden und dann
- die Header-Dateien der Module, die "importiert" werden sollen, sowie die
- normalen Standard-Header-Dateien.
- 4. Anschließend folgt die Header-Datei "GFEXPORT.H" und die Header-Datei des
- Moduls selbst.
- Mit dieser Vorgehensweise ist es möglich, wie in Modula Variablen und
- Funktionen bezogen auf das jeweilige Modul zu importieren bzw. exportieren.
- In dem Header-File "GFIMPORT.H" werden zusätzlich noch die Funktionen min und
- max, sowie der Typ BOOLEAN mit seinen Ausprägungen TRUE und FALSE definiert.
-
-
- 3. Die Struktur der GEM-Force-Library
- =====================================
-
- Aufbauend auf diese Modul-Struktur gliedert sich die GEM-Force-Library (intern)
- in 3 Module: das Modul GLOBAL, das Modul WINDOWS und das Modul TOS. Für jedes
- dieser Module gibt es ein ein eigenes Header-File, das Sie inkludieren müssen,
- wenn Sie Funktionen des jeweiligen Moduls nutzen wollen.
-
-
- 4. Modul GLOBAL
- ===============
-
- Dieses Modul stellt allgemeingültige Hilfsfunktionen für die GEM-Programmierung
- zur Verfügung. Soll dieses Modul von GEM-Force genutzt werden, ist die Header-
- Datei "GFGLOBAL.H" zu importieren. Die in diesem File enthaltenen Define-
- Anweisungen sind nicht so interessant; wer Interesse hat, schaue sie sich in
- der Datei selbst an.
- Erwähnenswert sind noch folgende Typ-Definitionen, die ebenfalls in der Header-
- Datei enthalten sind:
-
- typedef struct
- {
- int x, y, w, h;
- } RECT;
-
- typedef struct
- {
- long x, y, w, h;
- } LRECT;
-
- RECT und LRECT sind jeweils Typen für die Speicherung von Rechtecken.
-
- Ein weiterer Typ ist:
-
- typedef struct
- {
- int ascii_code;
- int scan_code;
- BOOLEAN shift;
- BOOLEAN ctrl;
- BOOLEAN alt;
- int kreturn;
- int kstate;
- } KEYINFO;
-
- KEYINFO enthält Informationen über eine Tastaturaktion.
-
- Es folgt nun eine Aufzählung der enthaltenen Funktionen:
-
-
- GLOBAL BOOLEAN init_gem ( void )
-
- Diese Funktion sollte zu Beginn aller GEM-Programme aufgerufen werden. Sie
- meldet das Programm zuerst beim VDI und dann bei den AES an und füllt dabei
- globale Variablen, die sich bei der GEM-Programmierung immer als nützlich
- erweisen:
- GLOBAL int appl_id die Application-ID der Applikation
- GLOBAL int phys_handle das physikalische Workstation-Handle des Bildschirms
- GLOBAL int vdi_handle das Handle der virtuellen Bildschirm-Workstation,
- welches für alle weiteren VDI-Aufrufe benötigt wird
- GLOBAL int tos die TOS-Version GLOBAL
- int colors die Anzahl der darstellbaren Farben (monochrom = 2 !)
- GLOBAL RECT desk das Rechteck des benutzbaren Bildschirms (ganzer
- Bildschirm abzüglich Menüleiste)
- GLOBAL RECT clip das aktuell eingestellte Clipping-Rechteck
- GLOBAL int gl_wbox, gl_hbox die Breite und Höhe der Box, die ein Zeichen des
- Systemzeichensatzes einschießt (z. B. 8 x 16)
- GLOBAL int gl_wchar, gl_hchar die Breite und Höhe eines Zeichens des
- Systemzeichensatzes
- GLOBAL int gl_wattr, gl_hattr die Breite und Höhe der Box, die ein Be-
- dienelement eines Fensters einschließt (z. B. die
- Closer-Box)
- GLOBAL long gdos 0, wenn kein GDOS installiert ist, sonst das Ergebnis
- des Aufrufs von vq_vgdos (siehe auch die Einträge im
- Header für Vergleiche !)
- Weiterhin werden noch folgende globale Variablen initialisiert:
- GLOBAL int blinkrate Blinkrate für PopUp-Menüs (Initialwert 2)
- GLOBAL BOOLEAN grow_shrink Zeichnen von Grow- bzw. Shrink-Boxen bei Fenstern
- und Dialogboxen (Initialwert TRUE)
- GLOBAL BOOLEAN save_bg automatisches Sichern des Hintergrundes bei Dialogboxen
- (Initialwert TRUE)
- Wie für die meisten BOOLEAN-Funktionen gilt: Die Funktion gibt TRUE zurück,
- wenn alles geklappt hat, sonst FALSE.
-
-
- GLOBAL void exit_gem ( void )
-
- Diese Funktion ist das Gegenstück zu init_gem und meldet das Programm beim GEM
- ab, indem sie die geöffnete virtuelle Bildschirm-Workstation schließt, den von
- einer geladenen Resource-Datei benötigten Speicherplatz wieder freigibt und
- appl_exit aufruft.
-
-
- GLOBAL BOOLEAN rsc_load ( char err_norsc, char *filename )
-
- In der Regel wird man bei GEM-Programmen mit RSC-Dateien arbeiten wollen;
- deshalb bietet diese Funktion einen vereinfachten Aufruf der Funktion
- rsrc_load; dazu wird die Maus als Biene dargestellt und die Datei geladen. Im
- Fehlerfall ertönt ein Glockensignal und eine Fehlermeldung wird (mit Hilfe
- einer Alert-Box) auf den Bildschirm gebracht. Um die Library sprachunabhängig
- und individuell einsetzbar zu machen, wird keine Standard-Fehlermeldung
- gemacht, sondern eine von Ihnen zu übergebende Alert-Meldung angezeigt. Im
- Erfolgsfall liefert die Funktion TRUE zurück.
-
-
- GLOBAL BOOLEAN init_tree ( int index, OBJECT **tree, BOOLEAN is_dialog);
-
- Mit Hilfe eines einzigen Funktionsaufrufes, der für jeden in Ihrer Resource-
- Datei enthaltenen Baum getätigt werden sollte, werden eine ganze Menge
- verschiedener Dinge für die Initialisierung eines Objekt-Baumes gemacht. Zuerst
- einmal wird die Adresse ermittelt; dazu wird der Parameter **tree benötigt, das
- heißt ein Zeiger auf einen Zeiger auf einen Objektbaum (ein Zeiger auf einen
- Zeiger ist notwendig, da der Zeiger selbst ja verändert werden soll).
- Des weiteren werden alle Images und Icons, die in diesem Baum enthalten sind,
- ins gerätespezifische Format umgewandelt, damit deren Darstellung auch auf
- Rechnern mit Grafikkarten richtig funktioniert.
- Besonderer Leckerbissen: Alle enthaltenen benutzerdefinierten Objekte (das sind
- Check-Boxes, Radio-Buttons, Überschriftenobjekte, eine "Move-Corner" für
- fliegende Dialoge und Unterstreichungen) werden fertig vorbereitet.
- Damit das funktionieren kann, sind ein paar Dinge notwendig: Es muß einen
- globalen OBJECT-Pointer namens userimg geben, der auf einen Objektbaum zeigt,
- der die Images der Check-Boxes und Radio-Buttons für die verschiedenen
- Auflösungen enthält. Dazu sollte einfach der in der mitgelieferten Datei
- GFUSRIMG.RSC enthaltene Dialog in Ihr eigenes Resource-File kopiert werden. Die
- Objekte in diesem Baum dürfen dabei auf gar keinen Fall andere Objekt-Nummern
- bekommen; am besten Sie verändern also nichts daran. Weitere Voraussetzung ist,
- daß dieser Baum als aller erster mit der Funktion init_tree vorbereitet wird
- (andernfalls kann später nicht auf dessen Adresse zugegriffen werden !).
- Wenn Sie nun benutzerdefinierte Objekte in Ihrer Resource-Datei verwenden
- wollen, sollten Sie diese aus der ebenfalls mitgelieferten Datei GFOBJLIB.RSC
- kopieren; hier sind normale Objekte enthalten, die als Platzhalter für die
- benutzerdefinierten Objekte dienen und die bereits einen entsprechenden
- extended type haben.
- Nach der Initialisierung mit init_tree werden dann die echten Objekte
- erscheinen, wenn der Dialog am Bildschirm angezeigt wird.
- Der letzte Parameter is_dialog ist mit TRUE zu belegen, wenn der Objekt-Baum
- ein Dialog ist, sonst mit FALSE.
-
-
- GLOBAL void dialog_on ( OBJECT *tree )
-
- Wir bleiben bei den Dialogen: Erster Schritt bei der Dialogverarbeitung ist es
- natürlich, die Dialoge erst einmal für den Benutzer sichtbar zu machen. Das
- können Sie mit Hilfe dieser Funktion erledigen, welche einen Objektbaum auf den
- Bildschirm zeichnet.
- Sie brauchen sich dabei weder um das Zentrieren des Dialogs, das Retten des
- Hintergrundes, die Maus oder sonst etwas kümmern: Dies alles und noch mehr wird
- automatisch erledigt. Eins ist jedoch zu beachten: Da intern nur ein einziger
- Speicherblock für das Retten des Hintergrunds benutzt werden kann, dürfen
- Dialoge nicht übereinander gezeichnet werden; andernfalls könnte nur der
- Hintergrund des letzten richtig restauriert werden, und es gäbe Probleme beim
- Freigeben dieses Speicherbereichs.
-
-
- GLOBAL void dialog_off ( OBJECT *tree )
-
- Unschwer zu erraten: dialog_off beseitigt einen Dialog wieder vom Bildschirm
- und kümmert sich ggf. um das Zurückkopieren des Hintergrundes usw.
-
-
- GLOBAL int form_dialog ( OBJECT *tree, int edit_object )
-
- Der Aufruf dieser Funktion ersetzt das normale form_do vollständig, arbeitet
- also einen Dialog ab, bis ein Exit- oder Touchexit-Button betätigt wird.
- "Nebenbei" werden noch fliegende Dialoge realisiert, sofern der Dialog ein
- entsprechendes Objekt enthält.
-
-
- GLOBAL int do_dialog ( OBJECT *tree, int edit_object )
-
- Der Aufruf dieser Funktion faßt die letzten drei Funktionen zusammen: Der
- Dialog wird dargestellt, verwaltet und wieder vom Bildschirm gelöscht. Sie
- können also eine ganze Dialogverarbeitung mit einem einzigen Befehl durchführen
- !
- Einen Haken hat das ganze natürlich: Wurde ein Touchexit-Button betätigt, ist
- der Dialog natürlich auch vom Bildschirm verschwunden, obwohl diese Art Objekte
- meist verwandt werden, wenn eine Aktion im Dialog ausgelöst werden soll, ohne
- daß dieser verschwindet.
- Aus diesem Grund wurden die vorherigen Funktionen für den Anwender global
- gehalten: So kann der Dialog dargestellt (dialog_on), in einer einfachen
- Schleife solange verarbeitet werden, bis ein "echtes" Exit-Objekt (also kein
- Touchexit-Objekt) betätigt wurde (form_dialog), und anschließend wieder vom
- Bildschirm gelöscht werden (dialog_off). Fertig !
-
-
- GLOBAL void store_dial ( OBJECT *tree )
-
- Jeder kennt die Dialogboxen, die zum Verlassen einen OK- und einen Abbruch-
- Button haben. Wird letzterer betätigt, werden die vorigen Inhalte wieder in die
- Dialogbox eingetragen (was man erst beim nächsten Aufruf zu sehen bekommt) und
- keine weitere Aktion ausgelöst.
- Dieser Mechanismus erfordert es, daß das Programm sich vor dem Verändern durch
- den Benutzer alle Textfelder und Buttons merkt. Und das erfordert wieder
- lästigen Programmieraufwand.
- Nicht so mit GEM-Force ! Obige Funktion erledigt dies für Sie, indem der
- gesamte Baum durchlaufen wird und Status bzw. Inhalt aller Objekte, die die
- Flags SELECTABLE oder EDITABLE haben, in internen Arrays gespeichert werden,
- und zwar bis zu 20 Buttons und 10 Textfelder mit einer maximalen Länge von 70
- Zeichen.
-
-
- GLOBAL void restore_dial ( OBJECT *tree )
-
- Wurde der Abbruch-Button betätigt, können Sie nun ganz einfach mit der Funktion
- restore_dial den Dialog wieder herstellen, ohne sich um Einzelheiten kümmern zu
- müssen.
-
-
- GLOBAL void draw_grow_shrink ( RECT *ende, int mode )
-
- Meistens, wenn man Grow- oder Shrink-Boxen zeichnen möchte, ist der Start- bzw.
- Endpunkt die Bildschirmmitte. Dieser Vorgang wird durch draw_grow_shrink
- vereinfacht, da Sie nur noch das größere Rechteck (das Zielrechteck bei Grow-
- bzw. das Quellrechteck Shrink-Boxen) angeben müssen, sowie den Parameter
- FMD_GROW bzw. FMD_SHRINK der AES-Funktion form_dial. Die Bildschirmmitte wird
- automatisch errechnet sowie die Boxen gezeichnet, sofern die Variable
- grow_shrink den Wert TRUE hat.
-
-
- GLOBAL void hide_mouse ( void )
-
- Nun kommen wir zu den Routinen, mit denen die Maus manipuliert werden kann. Die
- hier zuerst genannte läßt die Maus verschwinden. Intern wird hierzu ein Zähler
- verwaltet, der bewirkt, daß die Maus sooft ausgeschaltet werden muß, wie sie
- eingeschaltet wurde, bevor sie wirklich verschwindet. Umgekehrt gilt, daß die
- Maus genauso oft eingeschaltet werden muß, wie sie ausgeschaltet wurde, bevor
- sie erscheint.
- Welchen Sinn hat das ? Zum Beispiel wird in einer Fehlerroutine die Maus
- eingeschaltet, um eine Alert-Box verarbeiten zu können. Am Ende wird die Maus
- wieder ausgeschaltet. So schön, so gut. Was passiert aber nun, wenn die Maus
- vor Ausführen der Fehlerroutine bereits eingeschaltet war ? Würde der oben
- beschriebene Mechanismus nicht verwandt, würde sie am Ende der Routine wieder
- ausgeschaltet, obwohl vielleicht die aufrufende Funktion von einer
- angeschalteten Maus ausgeht. Dies kann mit diesem "Maus-Stack" nicht passieren.
-
-
- GLOBAL void show_mouse ( void )
-
- Diese Funktion schaltet die Maus erwartungsgemäß nach dem oben beschriebenen
- Mechanismus wieder ein.
-
-
- GLOBAL void busy_mouse ( void )
-
- Die Mausform "Biene" wird eingestellt. Auch für das Umschalten von Biene auf
- Pfeil und umgekehrt wird ein "Maus-Stack" für die Mausform (Biene oder Pfeil)
- verwendet.
-
-
- GLOBAL void arrow_mouse ( void )
-
- Das Umschalten von Biene auf Pfeil-Form erledigt diese Funktion.
-
-
- GLOBAL void set_mouse ( int number, MFORM *addr )
-
- Diese Routine setzt die aktuelle Mausform. Falls number 255 ist, wird auf die
- benutzerdefinierte Mausform umgeschaltet, auf die addr zeigt. Für den nächsten
- Befehl merkt sich die Funktion in der globalen Variablen mousenumber und
- mouseform die letzte Mausform.
-
-
- GLOBAL void last_mouse ( void )
-
- Schaltet auf die zuletzt eingeschaltete Mausform zurück.
-
-
- GLOBAL BOOLEAN select_file ( char *name, char *path, char *suffix, char *label,
- char *filename )
-
- Sollen in einem GEM-Programm Dateien geladen oder gesichert werden, kommt in
- der Regel die Dateiauswahlbox ins Spiel. Um deren Aufruf zu vereinfachen wurde
- diese Funktion geschrieben.
- name ist dabei der Name (ohne Pfad) der Datei, der in der Dateiauswahlbox als
- Default vorgegeben wird.
- path ist der Pfad obiger Datei, der ebenfalls in der Dateiauswahlbox angezeigt
- wird.
- suffix ist die Dateimaske einschließlich Extension, die darüber bestimmt,
- welche Dateien in der Dateiauswahlbox angezeigt werden (z. B. *.*, *.C etc.).
- label ist der Text, der oben in der Dateiauswahlbox angezeigt wird. Dieses
- Feature ist erst ab TOS 1.04 verfügbar, was aber von der Routine berücksichtigt
- wird.
- Der Rückgabewert der Funktion ist TRUE, wenn der OK-Button betätigt wurde und
- zusätzlich noch ein Dateiname ausgewählt wurde, der dann in filename steht. In
- allen anderen Fällen wird FALSE zurückgegeben.
-
-
- GLOBAL void divide_filename ( char *filename, char *path, char *file)
-
- In der letzten Funktion wurden als Eingabeparameter Pfad und Dateiname
- verlangt. Damit das Aufsplitten eines vollständigen Pfadnamens möglichst
- komfortabel und einfach ist, wurde diese Funktion geschaffen.
- Der Parameter filename gibt den vollständigen Dateinamen an. Dieser wird in
- Pfad und reinen Dateinamen gesplittet und die Ergebnisse in den anderen beiden
- Variablen gespeichert, und zwar genau dann, wenn der jeweilige Zeiger kein
- NULL-Zeiger ist. So ist es möglich z. B. nur den Pfad, nicht aber den
- Dateinamen, zu extrahieren.
-
-
- GLOBAL void call_mortimer ( char *command )
-
- Wenn Sie stolzer Besitzer des Multi-Utilities MORTIMER der Pforzheimer Firma
- OMIKRON sind, dann können Sie mit dieser Funktion Ihren Buttler aus Ihrem C-
- Programm heraus aufrufen, und zwar direkt mit einem Kommando (siehe MORTIMER-
- Handbuch). Ist kein MORTIMER installiert, bewirkt der Funktionsaufruf nichts.
-
-
- GLOBAL void do_state (OBJECT *tree, int obj, unsigned int state )
- GLOBAL void undo_state (OBJECT *tree, int obj, unsigned int state)
-
- Jetzt kommen wir zu den Funktionen, die sich mit der Manipulation von Objekten
- beschäftigen. Die ersten beiden hier genannten befassen sich mit dem Status von
- Objekten.
- Mit do_state können ein oder mehrere Status-Flags des Objektes obj in
- Objektbaum tree gesetzt werden. Dazu sind die in AES.H definierten Flags zu
- verwenden und ggf. mit "oder" zu verknüpfen.
- Mit undo_state können analog ein oder mehrere Status-Flags zurückgesetzt
- werden.
-
-
- GLOBAL void flip_state (OBJECT *tree, int obj, unsigned int state )
-
- Diese und alle weiteren Funktionen, die mit flip beginnen, setzen einen oder
- mehrere Flags, wenn diese vorher nicht gesetzt waren, oder setzen diese zurück,
- falls sie vorher gesetzt waren.
-
-
- GLOBAL int find_state (OBJECT *tree, int obj, unsigned int state )
-
- Diese Funktion erlaubt es, nach einem Objekt zu suchen, das einen bestimmten
- Status hat. Dabei wird ab dem Objekt obj gesucht. Wurde kein Objekt gefunden,
- wird NIL zurückgegeben.
-
-
- GLOBAL BOOLEAN is_state (OBJECT *tree, int obj, unsigned int state )
-
- Natürlich müssen der Status und andere Objekt-Attribute auch abgefragt werden
- können. Dies geschieht mit den Objektfunktionen, die mit is beginnen.
-
-
- GLOBAL void do_flags (OBJECT *tree, int obj, unsigned int flag )
- GLOBAL void undo_flags (OBJECT *tree, int obj, unsigned int flag)
- GLOBAL void flip_flags (OBJECT *tree, int obj, unsigned int flag )
- GLOBAL int find_flags (OBJECT *tree, int obj, unsigned int flag )
- GLOBAL BOOLEAN is_flags (OBJECT *tree, int obj, unsigned int flag )
-
- Analog zu den eben betrachteten Funktionen arbeiten diese Funktionen, die sich
- anstatt mit dem Objekt-Status mit den Objekt-Flags beschäftigen.
-
-
- GLOBAL int find_type ( OBJECT *tree, int obj, unsigned int type)
-
- Wenn Sie einmal ein Objekt eines bestimmten Typs in einem Objekt-Baum suchen,
- wird Ihnen diese Funktion weiterhelfen. Auch hier kann wieder ein Start-Objekt
- angegeben werden, ab dem gesucht werden soll. Wurde kein passendes Objekt
- gefunden, wird NIL zurückgegeben.
-
-
- GLOBAL void set_rbutton ( OBJECT *tree, int obj, int lower,int upper )
-
- Will man einen Radio-Button selektieren, müssen vorher alle anderen Radio-
- Buttons deselektiert werden. Dies erledigt diese Funktion automatisch. Neben
- dem Objekt, das selektiert werden soll müssen daher noch der erste und der
- letzte der zusammengehörigen Radio-Buttons angegeben werden. Objekte, die sich
- zwar durch ihre Objekt-Nummer zwischen diesen Grenzen befinden, aber keine
- Radio-Buttons sind (was immer mal passieren kann), werden dabei nicht
- verändert.
-
-
- GLOBAL int get_rbutton ( OBJECT *tree, int obj )
-
- Natürlich muß man auch Radio-Buttons abfragen können. Dazu dient diese Routine,
- der außer der Adresse des Objekt-Baums auch noch ein Objekt angegeben werden
- muß, ab dem gesucht wird. Voraussetzung ist allerdings, daß auch wirklich ein
- Radio-Button selektiert ist.
-
-
- GLOBAL void deselect_obj ( OBJECT *obj, int ind )
-
- Eine fast überflüssige Funktion (kann durch undo_state mit entsprechenden
- Parametern ersetzt werden), aber es gibt sie trotzdem. Wie der Name bereits
- verrät deselektiert sie Objekte.
-
-
- GLOBAL void set_te_ptext ( OBJECT *obj, int ind, const char *str )
-
- Diese nützliche Routine kopiert einen String in ein Textobjekt. Dabei wird die
- maximale Länge des Objektes berücksichtigt und nötigenfalls der String gekürzt.
-
-
- GLOBAL void objc_rect ( OBJECT *tree, int obj, RECT *rect, BOOLEAN calc_border)
-
- In vielen Fällen kann es nützlich sein, ein Rechteck zu ermitteln, das ein
- bestimmtes Objekt einhüllt. Dies tut obige Funktion, wobei das ermittelte
- Rechteck anschließend in rect steht. Der letzte Parameter gibt dabei noch an,
- ob der Rand bei Objekten des Typs G_BOX, G_IBOX, G_BOXCHAR mit berücksichtigt
- werden soll. Zu diesem Rand gehören auch die Attribute SHADOWED und OUTLINED.
-
-
- GLOBAL void text_default ( void )
-
- Oftmals, wenn man Text mit Hilfe von VDI-Funktionen ausgeben will, muß man
- vorher mühsam den Textstil, den Font richtiger Größe, die Ausrichtung u. v. m.
- einstellen, obwohl man eigentlich den Text nur "ganz normal" ausgeben möchte.
- Abhilfe schafft da diese Funktion, die alle diese Attribute auf Default-Werte
- zurücksetzt und den Standard-Systemfont (z. B. 8 x 16 bei monochrom,
- hochauflösend) einstellt.
-
-
- GLOBAL void line_default ( void )
-
- Das gleiche in grün (?!), diesmal nur für die Ausgabe von Linien.
-
-
- GLOBAL void bell( void )
-
- In den meisten Programmen macht sich ein kleiner "Ping" hier und da ganz gut
- (z. B. wenn ein Fehler aufgetreten ist). Dies erledigt die Funktion bell.
-
-
- GLOBAL void rect2array ( const RECT *rect, int *array )
- GLOBAL void array2rect ( const int *array, RECT *rect )
-
- Alle Jahre wieder kommt man in die Verlegenheit, mit Rechtecken und
- verschiedenen Arten von Arrays herumzuwirbeln. Um Ihnen einen Großteil dieser
- Arbeit abzunehmen folgen nun eine ganze Reihe von Funktionen, die sich mit
- Rechtecken auseinandersetzen.
- Die ersten beiden kopieren den Inhalt eines Rechtecks in ein Array, das eine
- Punktliste enthalten soll (also x1, y1, x2 und y2), und umgekehrt. Die dazu
- notwendigen Umrechnungen werden dabei automatisch durchgeführt.
-
-
- GLOBAL void xywh2array ( int x, int y, int w, int h, int *array )
- GLOBAL void array2xywh ( const int *array, int *x, int *y, int *w, int *h )
- GLOBAL void xywh2rect ( int x, int y, int w, int h, RECT *rect )
- GLOBAL void rect2xywh ( const RECT *rect, int *x, int *y, int *w, int *h)
-
- Manchmal hat man Position, Breite und Höhe eines Rechtecks auch in getrennten
- Variablen gespeichert (x, y, w und h) und möchte sie nun in ein Array oder ein
- Rechteck kopieren oder umgekehrt. Auch hierfür gibt es entsprechende
- Funktionen.
-
-
- GLOBAL BOOLEAN rc_intersect (const RECT *p1, RECT *p2)
-
- Besonders im Rahmen der Fensterverwaltung kommt es vor, daß Rechtecke
- miteinander geschnitten werden müssen. Dies erledigt diese Routine für Sie,
- wobei das Ergebnis im zweiten übergebenen Rechteck abgespeichert wird und der
- Rückgabewert Auskunft darüber gibt, ob sich die Rechtecke überhaupt schneiden.
-
-
- GLOBAL void rc_union ( const RECT *p1, RECT *p2)
-
- Das Gegenstück zum Schneiden von Rechtecken ist das Vereinigen zu einem großen
- Rechteck. Das Ergebnis wird wieder im zweiten Parameter abgelegt.
-
-
- GLOBAL BOOLEAN rc_equal ( const RECT *p1, const RECT *p2)
-
- Ein Vergleich, ob zwei Rechtecke identisch sind, kann mit rc_equal durchgeführt
- werden.
-
-
- GLOBAL void set_clip ( BOOLEAN set, const RECT *r )
-
- Besonders im Zusammenhang mit Fenstern ist das Clipping angesagt. Die obige
- Funktion setzt das Clipping-Rectangle (set=TRUE) oder setzt ein gesetztes
- Clipping zurück (set=FALSE). Ist der übergebene Zeiger ein NULL-Zeiger, wird
- der Desktop als Clipping-Bereich verwendet. Es wird auch sichergestellt, daß in
- jedem Fall maximal der Desktop selbst als Clipping-Bereich verwendet wird.
- Damit überall im Programm das gerade aktive Clipping-Rechteck abgefragt werden
- kann, wird dieses in der globalen Rechteck-Variablen clip gespeichert.
-
-
- GLOBAL BOOLEAN inside ( int x, int y, const RECT *r )
-
- Die letzte Rechteck-Funktion testet, ob ein bestimmter Punkt innerhalb eines
- Rechtecks liegt.
-
-
- GLOBAL BOOLEAN find_menu_item ( OBJECT *menu, KEYINFO *ki, int *title, int
- *item )
-
- In den neueren GEM-Programmen ist es Gang und Gäbe, mit Tastatur-Shortcuts
- Menü-Funktionen auszulösen. Im Programm muß nach einer solchen Eingabe meist
- mit Hilfe von langen switch-Statements die Tastaturaktion abgefragt und die
- richtige Funktion aufgerufen werden. Wird dann der Shortcut geändert, müssen
- Resource-File und Programm mühsam angepaßt werden.
- Die Benutzer von GEM-Force haben es da viel einfacher: Die Funktion
- find_menu_item erledigt bereits eine ganze Menge für den Programmierer, und
- zwar wurde hier ein anderer, geschickterer Weg beschritten: Sie übergeben der
- Funktion nur Informationen über das Keyboard-Event (siehe nächste Funktion),
- und die Routine gibt Ihnen den gewählten Menüeintrag zurück, der direkt anhand
- der Resource im Speicher gesucht wird. Dabei gibt der Return-Wert der Funktion
- an, ob ein Menüeintrag gefunden wurde oder nicht. Anschließend können Sie im
- Programm so verfahren, als wäre das Menü direkt ausgewählt worden.
- Sollen die Shortcuts geändert werden, reicht es nun, die RSC-Datei anzupassen.
- Die Funktion erkennt bisher folgende Tastaturkombinationen:
- - Control + Taste ("Dach" und Zeichen),
- - Shift + Funktionstaste (Pfeil nach oben und "Fxx") und
- - Alternate + Taste (Raute und Zeichen).
- Andere Kombinationen werden bisher noch nicht erkannt.
-
-
- GLOBAL void get_keyinfo ( int mkstate, int mkreturn, KEYINFO *ki )
-
- Der in der letzten Funktion zu übergebende Zeiger ki ist ein Zeiger auf eine
- KEYINFO-Struktur. Eine solche ist in Ihrem Programm anzulegen und nach einem
- Tastatur-Event mit obigem Funktionsaufruf zu initialisieren. Die übergebenen
- Parameter sind die gleichnamigen Rückgabeparameter der evnt_multi-Funktion der
- AES.
-
-
- GLOBAL int popup_menu ( OBJECT *tree, int obj, int x, int y, int center_obj,
- BOOLEAN relative, int bmsk )
-
- Als Bonbon dieses Teiles der GEM-Force-Library noch eine handliche Funktion für
- die komplette Verwaltung von PopUp-Menüs. Es wird davon ausgegangen, daß das
- PopUp-Menü sich als Kind-Objekt in einem Objekt-Baum befindet. In der Regel ist
- ohnehin üblich, PopUps und ähnliche Objekte in einem Objekt-Baum zu "sammeln".
- Daher ist nicht nur ein Objekt-Baum anzugeben, sondern auch der Index des
- Vater-Objektes des PopUp-Menüs. x und y sind Koordinaten, an denen das Menü
- erscheinen soll, und zwar entweder als absolute Koordinaten (relative=FALSE)
- oder als Koordinaten relativ zum Mauszeiger (relative=TRUE). Die Funktion
- überwacht selbständig, daß das Menü nicht aus dem Bildschirm herausragt.
- Als weitere Option ist es möglich, mit center_obj ein Objekt (einen Eintrag im
- PopUp-Menü) anzugeben, auf dem der Mauszeiger beim erscheinen des Menüs stehen
- soll. Schließlich kann mit bmsk noch gesteuert werden, mit welchem Mausknopf
- das Menü verlassen werden soll, indem eine entsprechende Maske (das
- niederwertigste Bit ist der linke Mausknopf usw.) angegeben wird.
- Am besten, Sie experimentieren ein wenig mit den Parametern, um zu sehen,
- welcher was bewirkt.
-
-
- 5. Modul WINDOWS
- ================
-
- Dieses Modul stellt Funktionen für die Fensterverwaltung in Form eines Window-
- Managers zur Verfügung. Soll dieses GEM-Force-Modul genutzt werden, ist die
- Header-Datei "GFWINDWS.H" zu importieren.
- Bevor näher auf die Funktionen eingegangen wird, soll das dem Window-Manager
- zugrundeliegende Konzept näher erläutert werden.
- Zuerst einmal ist wichtig zu wissen, wie ein Fenster eingeteilt ist.
- Der Fensterinhalt ist in Work- und Scroll-Bereich eingeteilt. Der Work-Bereich
- umfaßt immer das gesamte Fensterinnere, während der Scroll-Bereich kleiner sein
- kann, so daß (wie in der Abbildung zu sehen) ein Rand entstehen kann, welcher
- bei Betätigung der Slider oder ähnlichen Aktionen nicht verändert werden.
- Anders der Scrollbereich, denn auf diesen beziehen sich diese Aktionen, er wird
- also entsprechend gescrollt. Natürlich muß es nicht alle Ränder geben bzw. muß
- es überhaupt Randbereiche geben. In letzterem Fall wäre also der Workbereich
- genauso groß wie der Scrollbereich.
- Kommen wir nun zur grundlegendsten Struktur des Moduls WINDOWS, und zwar der
- Struktur, die alle Informationen zu einem Fenster enthält:
-
- typedef struct window
- {
- int handle; /* Handle für Fenster */
- BOOLEAN opened; /* Fenster geöffnet */
- unsigned int flags; /* Flags des Fensters */
- unsigned int kind; /* Art des Fensters */
- int class; /* Klasse des Fensters */
- LRECT doc; /* Dokumentgröße, Position */
- int xfac; /* X-Factor des Dokumentes */
- int yfac; /* Y-Factor des Dokumentes */
- int xunits; /* X-Scroll-Einheiten */
- int yunits; /* Y-Scroll-Einheiten */
- RECT scroll; /* Scrollbereich */
- RECT work; /* Arbeitsbereich */
- long special; /* für speziellen Gebrauch */
- char name[128]; /* Name des Fensters */
- char info[128]; /* Infozeile im Fenster */
- OBJECT *object; /* Objektbaum für Fenster */
- BOOLEAN (*test) (WINDOWP, int );/* Test vor einer Aktion */
- void (*open) (WINDOWP); /* Aktion vor dem Öffnen */
- void (*close) (WINDOWP); /* Aktion nach dem Schließen */
- void (*delete) (WINDOWP); /* Aktion vor dem Löschen */
- void (*draw) (WINDOWP); /* Zeichnen-Funktion */
- void (*arrow) (WINDOWP,int,long,long ); /* Pfeil-Aktion */
- void (*snap) (WINDOWP, RECT *, int ); /* Schnapp-Aktion */
- void (*top) (WINDOWP); /* Aktion nach Top */
- void (*untop) (WINDOWP); /* Aktion vor Untop */
- } WINDOW;
-
- Der hier vielfach vorkommende Typ WINDOWP ist als Zeiger auf die Struktur
- WINDOW definiert. Wer hier über Formulierungen wie "BOOLEAN (*test) (WINDOWP,
- int );" stolpert und diese nicht deuten kann: Hier wird eine hervorragende
- Eigenschaft der Programmiersprache C genutzt, und zwar die Speicherung von
- Zeigern auf Funktionen. Eine Zuweisung an einen solchen Zeiger würde über den
- Namen der Funktion geschehen, denn der Name einer Funktion ist ein Zeiger auf
- dieselbe (ähnlich den Arrays). Ein Referenzieren eines solchen Zeigers mit
- Hilfe des "*"-Operators würde eine solche Funktion aufrufen. Für weitergehende
- Informationen zu diesem Thema sei auf einschlägige C-Literatur verwiesen.
- Die einzelnen Struktur-Elemente haben folgende Bedeutung:
-
- int handle
- Dies ist das Handle, das bei den AES ein Fenster identifiziert und über das mit
- AES-Funktionen auf Fenster zugegriffen wird.
-
- BOOLEAN opened
- Der Zustand des Fensters, nämlich ob es geöffnet ist oder nicht.
-
- unsigned int flags
- Verschiedene Flags, die das Verhalten des Fensters beeinflussen. Die Flags
- werden vom Window-Manager weitestgehend selbst gesetzt und verwaltet. Dabei
- existieren folgende Flags:
- # define WI_NONE 0x0000 /* Keine Flags */
- # define WI_FULLED 0x0001 /* Fenster auf voller Groesse */
- # define WI_LOCKED 0x0002 /* Fenster gelockt */
- # define WI_FIRSTDRW 0x0004 /* Fenster erstesmal gezeichnet */
- # define WI_ONTOP 0x0010 /* Fenster ist oben */
- # define WI_NOTOP 0x0020 /* Fenster darf nicht nach oben */
- # define WI_RESIDENT 0x0040 /* Fenster resident */
- # define WI_NOSCROLL 0x0100 /* kein Scrolling */
-
- unsigned int kind
- Informationen darüber, welche Fensterelemente das Fenster hat (siehe AES.H).
- Der Einfachheit befindet sich in GFWINDWS.H noch das Makro ALL für alle
- Fensterelemente.
-
- int class
- Die Klasse des Fensters, d. h. die Zuordnung zu einer Klasse von Fenstern, die
- die gleichen Eigenschaften haben. Die Klasse kann vom Benutzer frei definiert
- werden. Nur die Klasse CL_TEXT wird von GEM-Force genutzt und bezeichnet Text-
- Fenster.
-
- LRECT doc
- Fenster zeigen in der Regel den Ausschnitt eines größeren Objektes an, sei es
- ein Dokument, eine Grafik etc. Ausgehend von dieser Überlegung wird in doc.w
- und doc.h die Größe dieses Dokuments angegeben, und zwar in Einheiten (Pixel
- bei Bildern, Buchstaben bei Text-Dokumenten usw.). doc.x und doc.y geben die
- aktuelle Position des Fenster-Ausschnitts innerhalb des Dokumentes an.
-
- int xfac, yfac
- Da die Angaben in den letzten beschrieben Variablen sich immer auf Einheiten
- (Buchstaben, Pixel usw.) beziehen, wird noch die Information benötigt, wieviele
- Pixel eine Einheit umfaßt, und zwar sowohl in x- als auch in y-Richtung.
- Minimal kann hier jeweils eine 1 eingetragen werden. Bei Buchstaben des
- Systemzeichensatzes wären die beiden Werte z. B. 8 und 16.
-
- int xuntits, yuntits
- Soll in einem Dokument gescrollt werden, muß bekannt sein, um wieviel Einheiten
- sich der Bildausschnitt verschiebt, wenn ein Pfeil im Fensterrandbereich
- angeklickt wird. Diese Information wird für x- und y-Richtung in obigen
- Variablen abgelegt.
-
- RECT scroll
- Die Größe des weiter oben beschriebenen Scroll-Bereichs wird in dieser Variable
- gespeichert. Maximal kann er die Größe des Work-Bereichs annehmen.
-
- RECT work
- Analog dazu die Größe des Work-Bereichs.
-
- long special
- Wer kennt es nicht, das ob_spec-Element der AES-Objekt-Struktur. Es dient zum
- Aufnehmen verschiedener Informationen, besonders Zeiger auf diverse Strukturen.
- Grundvoraussetzung ist an dieser Stelle natürlich das saubere Casting auf
- Zeiger des entsprechenden Typs.
- Die Funktion dieser Variable ist im Grunde die gleiche: Es soll die Möglichkeit
- geschaffen werden, weitere Informationen einem Fenster zuzuordnen, indem man
- einen Zeiger auf diese Informationen hier speichert. Natürlich kann dies auch
- eine einfache long-Zahl sein. So wird z. B. für Textfenster in dieser Variablen
- ein Zeiger auf ein Text-Array gespeichert.
-
- char name[128]
- Damit das Kind auch einen Namen hat: der Fenstertitel.
-
- char info[128]
- Der Text für die Infozeile.
-
- OBJECT *object
- Eine weitere Option für ein Fenster ist es, einen Objekt-Baum darin anzeigen zu
- lassen. Wenn Sie diese Möglichkeit nutzen wollen, geben Sie hier einen
- entsprechenden Zeiger an. Zu beachten ist, daß das Objekt nur im Scroll-
- Bereich, nicht aber im Randbereich (sofern überhaupt vorhanden) gezeichnet
- wird.
- Viele Aktionen (z. B. das Zeichnen des Objektes und das Anpassen der
- Koordinaten beim Verschieben des Fensters) werden Ihnen vom Window-Manager
- abgenommen, so daß Sie sich nur noch um die wichtigen Dinge kümmern müssen. Am
- besten Sie probieren es einfach mal aus.
-
- BOOLEAN (*test) ( WINDOWP window, int action )
- Hier kommen wir endlich zum ersten in der Struktur enthaltenen Zeiger auf eine
- Funktion. (Noch eine kurze Anmerkung: Wenn Sie Ihre eigenen Funktionen in
- diesen Zeigern einhängen, ist darauf zu achten, daß diese Funktionen jeweils
- die Parameter entgegennehmen müssen, die im Prototypen beschrieben sind ! Falls
- Sie keine Funktion einhängen wollen, lassen Sie einfach den Initialwert NULL im
- Zeiger stehen.)
- Diese Routine wird vom Window-Manager aufgerufen, bevor ein Fenster geschlossen
- oder gelöscht wird. Der zweite Parameter gibt dabei die Aktion an, die gerade
- ausgeführt werden soll (DO_CLOSE, DO_DELETE). Sie können in der eingehängten
- Funktion nun testen, ob die Aktion tatsächlich durchgeführt werden soll; falls
- nicht geben Sie einfach FALSE zurück, andernfalls TRUE.
-
- void (*open) ( WINDOWP window )
- Die Funktion wird unmittelbar vor dem Öffnen eines Fensters aufgerufen, so daß
- Sie noch bestimmte Arbeiten durchführen können, bevor das Fenster wirklich
- erscheint.
-
- void (*delete) ( WINDOWP window )
- Die Funktion wird unmittelbar vor dem Löschen eines Fensters aufgerufen.
-
- void (*draw) ( WINDOWP window )
- Dies ist wohl mit Abstand die wichtigste Routine in der Fensterstruktur, denn
- sie ist für das Zeichnen des Fensterinhalts verantwortlich und wird häufig vom
- Window-Manager aufgerufen. Wichtig in diesem Zusammenhang ist, daß Sie sich
- nicht mehr um das Clipping kümmern müssen; das erledigt GEM-Force bereits für
- Sie. Falls Sie in Ihrer Funktion Informationen über das Clipping-Rectangle
- benötigen, können Sie in der globalen Variablen RECT clip nachsehen.
-
- void (*arrow) ( WINDOWP window ,int dir,long oldpos, long newpos )
- Diese Funktion wird aufgerufen, wenn der Benutzer einen Pfeil angeklickt hat
- oder einen Schieber bewegt oder angeklickt hat. dir gibt dabei die Richtung an
- (HORIZONTAL, VERTICAL). oldpos ist die alte Position, newpos die neue Position
- im Dokument (siehe doc), abhängig von dir entweder horizontal oder vertikal.
- Innerhalb dieser Funktion sollten
- 1. die neue Position innerhalb des Dokuments in doc übertragen werden,
- 2. die Slider neu gesetzt werden und
- 3. der Fensterinhalt gescrollt werden.
- Voraussetzung ist natürlich, daß Sie die jeweilige Scroll-Aktion erlauben
- wollen; andernfalls brauchen Sie obige Arbeiten natürlich nicht zu erledigen.
- Ggf. können auch noch andere sinnvolle Dinge erledigt werden, z. B. das
- Vorrücken eines internen Cursors für Textzeilen u. v. m.
-
- void (*snap) ( WINDOWP window, RECT *new, int mode )
- Wird ein Fenster bewegt oder vergrößert/verkleinert, ist es oft sinnvoll, das
- Fenster auf eine bestimmte Position oder Größe einzurasten (z. B. bei
- Textfenstern auf ganze Buchstaben und auf eine durch 8 teilbare x-Position).
- new gibt in diesem Zusammenhang die "angeforderte" Größe und Position des
- gesamten Fensters an und kann von Ihnen in Ihrer Funktion verändert werden.
- mode zeigt an, ob das Fenster bewegt (MOVED) oder in seiner Größe verändert
- (SIZED) oder beides wurde.
- Zu beachten ist, daß beim ersten Öffnen eines Fensters kein Snapping
- stattfindet; Sie müssen also selbst Sorge dafür tragen, daß das Fenster zu
- diesem Zeitpunkt die richtige Größe und Position hat !
-
- void (*top) (WINDOWP window)
- Wenn ein Fenster nach oben gebracht wird, so wird diese Funktion angesprungen.
- Dies kann in zwei Fällen passieren:
- 1. Die AES senden die Message WM_TOPPED an die Applikation.
- 2. Ein Fenster wird geschlossen, und das bis dahin zweitoberste Fenster kommt
- nach oben. In einem solchen Fall sorgt GEM-Force dafür, daß diese Routine für
- das neue oberste Fenster angesprungen wird.
-
- void (*untop) (WINDOWP window)
- Diese Funktion ist das Gegenstück zur letzten Funktion: Hier wird das bisher
- oberste Fenster nach unten gebracht, und zwar wenn ein anderes Fenster getoppt
- wird oder ein neues Fenster geöffnet wird.
- Da eine entsprechende Message im ATARI-GEM noch nicht implementiert ist, sorgt
- GEM-Force selbst dafür.
-
- So, geschafft. Jetzt sollten Sie das Prinzip des GEM-Force-Window-Managers
- verstanden haben, so daß wir uns jetzt den "echten" Funktionen im einzelnen
- zuwenden können.
-
-
- GLOBAL BOOLEAN init_windows ( char *err_nowindow, int max_reswind )
-
- Wenn Sie Funktionen aus dem Windows-Modul von GEM-Force verwenden wollen, muß
- dieses Modul zu Beginn initialisiert werden. Dies geschieht mit obiger
- Funktion. Zu übergeben sind eine Alert-Meldung, die immer dann angezeigt wird,
- wenn ein Fenster geöffnet werden soll, aber keines mehr zur Verfügung steht,
- und die gewünschte Anzahl der maximal gleichzeitig im Speicher residenten
- Fenster.
- Das Grundprinzip des Window-Managers ist es, Fenster mit ihrer Window-Struktur
- im Speicher zu halten, unabhängig davon, ob sie geöffnet, also sichtbar, oder
- geschlossen sind. Dafür muß natürlich Speicherplatz reserviert werden, wozu
- wiederum die maximale Anzahl Fenster bekannt sein muß. Die tatsächlich
- reservierte Anzahl kann unter Umständen (z. B. bei Speichermangel) auch kleiner
- sein.
- Der Return-Wert ist TRUE, wenn wenigstens Speicher für ein einziges Fenster
- reserviert werden konnte, FALSE sonst.
-
-
- GLOBAL void exit_windows ( void )
-
- Um Ihr Programm zu terminieren sollten Sie auch diese Funktion aufrufen, denn
- sie schließt alle Fenster, löscht diese und gibt den reservierten Speicher der
- Fenster-Strukturen wieder frei.
-
-
- GLOBAL BOOLEAN handle_window_events ( int *msg )
-
- Diese Funktion ist das Kernstück des Window-Managers. Sie sollte direkt nach
- Ihrer evnt_multi-Schleife aufgerufen werden, wobei ein Zeiger auf den Event-
- Buffer übergeben wird. In ihr werden alle für den Window-Manager relevanten
- (Message-) Events verarbeitet und an die einzelnen Fenster weitergeleitet.
- Textfenster (siehe weiter unten) werden an dieser Stelle ebenfalls voll-
- automatisch verwaltet.
- Wurde das Event innerhalb der Funktion verarbeitet, wird TRUE zurückgegeben,
- sonst FALSE.
- Generell gilt: GEM-Force verarbeitet in seinem Window-Manager nur Message-
- Events. Alle anderen Events sind vom Programmierer selbst zu verarbeiten.
-
-
- GLOBAL WINDOWP create_window ( unsigned int kind, int class )
-
- Bevor Fenster-Events verarbeitet werden können, muß man natürlich erst einmal
- Fenster produzieren. Dazu rufen Sie obige Funktion auf und übergeben ihr die
- Art des gewünschten Fensters (Flags aus AES.H) sowie die Klasse des Fensters.
- Die Fenster-Klasse ist eine von Ihnen frei vorzugebende Klassifizierung von
- Fenstern, d. h. in der Regel ein Gruppenbegriff für eine bestimmte Art Fenster.
- Nur die Klasse CL_TEXT ist bereits vordefiniert (siehe weiter unten).
- Als Rückgabewert der Funktion bekommen Sie einen Zeiger auf die zum Fenster
- gehörige Window-Struktur. Haben Sie ein Fenster erfolgreich kreiert
- (Rückgabewert ungleich NULL), sollten Sie selbst - abgesehen von Art und Klasse
- - alle anderen (wichtigen) Elemente in der Fensterstruktur initialisieren.
- Funktionszeiger brauchen nur dann initialisiert zu werden, wenn Sie benötigt
- werden; andernfalls können Sie die NULL-Zeiger darin stehen lassen, die GEM-
- Force automatisch in die Struktur schreibt.
- Konnte kein Fenster mehr kreiert werden (nicht mehr genug Speicher, siehe
- init_windows), wird die bei init_gem angegebene Alert-Meldung angezeigt.
-
-
- GLOBAL void delete_window ( WINDOWP window )
-
- Soll ein Fenster auf Nimmer-Wiedersehen verschwinden, steht Ihnen diese
- Funktion zur Verfügung. Sollte das betreffende Fenster noch geöffnet sein, wird
- es vor dem Löschen noch geschlossen. Anschließend wird die Fensterstruktur
- gelöscht; das Fenster ist nicht mehr existent. Ausnahme: Ist eine Testfunktion
- in der Fensterstruktur eingehängt, und gibt diese FALSE zurück, wird das
- Fenster nicht gelöscht.
-
-
- GLOBAL BOOLEAN open_window ( WINDOWP window )
-
- Ein Fenster zu öffnen ist mit dieser Routine möglich. Sind noch GEM-Fenster
- verfügbar, wird das Fenster gezeichnet und der gesamte Fensterinhalt mit weiß
- initialisiert (Return-Wert TRUE). Andernfalls erscheint die bei init_gem
- angegebene Alert-Meldung (Return-Wert FALSE).
- Beim Öffnen eines Fensters werden ausgehend von der Bildschirmmitte Grow-Boxes
- gezeichnet, sofern die globale Variable grow_shrink den Wert TRUE hat.
- Wenn eine entsprechende open-Funktion in die Fensterstruktur eingehängt ist,
- wird diese unmittelbar vor dem Öffnen angesprungen.
-
-
- GLOBAL void close_window ( WINDOWP window )
-
- Dies ist das Gegenstück zur letzten Funktion. Beim Schließen eines Fensters
- werden ausgehend von der Bildschirmmitte Shrink-Boxes gezeichnet, sofern die
- globale Variable grow_shrink den Wert TRUE hat.
- Wenn eine entsprechende close-Funktion in die Fensterstruktur eingehängt ist,
- wird diese unmittelbar vor dem Schließen angesprungen.
- Ist eine test-Funktion in der Fensterstruktur eingehängt, und gibt diese FALSE
- zurück, wird das Fenster nicht geschlossen.
-
-
- GLOBAL void close_top ( void )
-
- Das oberste Fenster wird geschlossen.
-
-
- GLOBAL void close_all ( BOOLEAN delete )
-
- Alle GEM-Force-Fenster werden geschlossen. Ist der zweite Parameter TRUE,
- werden die Fenster zusätzlich auch gelöscht.
-
-
- GLOBAL void draw_window ( WINDOWP window )
-
- Der gesamte Fensterinhalt wird - ohne die Rechteckliste zu berücksichtigen -
- neu gezeichnet; soll nur ein Teil neu gezeichnet werden, muß das Clipping
- vorher entsprechend gesetzt werden. An dieser Stelle wird die von Ihnen in die
- Fensterstruktur eingehängte Zeichenroutine benutzt. Ein eingehängter Objektbaum
- wird automatisch gezeichnet. Die Maus wird selbständig versteckt.
-
-
- GLOBAL void redraw_window ( WINDOWP window, const RECT *area)
-
- Ein bestimmter Bereich wird unter Berücksichtigung der Rechteckliste neu
- gezeichnet.
-
-
- GLOBAL void top_window ( WINDOWP window )
-
- Ein Fenster wird nach oben gebracht, d. h. getoppt, sofern die Fenster-Flags
- (siehe oben) dies zulassen. Eine von Ihnen eingehängte top-Funktion wird
- anschließend angesprungen.
-
-
- GLOBAL void untop_window ( WINDOWP window )
-
- Ein Fenster wird von einem anderen (nach oben gebrachten oder neu geöffneten
- Fenster) erstmalig verdeckt (bzw. simuliert diese Funktion dies). Die Funktion
- setzt die entsprechenden Flags und ruft ggf. eine in die Fensterstruktur
- eingehängte untop-Routine auf.
-
-
- GLOBAL void scroll_window ( WINDOWP window, int dir, long delta )
-
- Der Inhalt eines Fensters wird um eine beliebige Anzahl von Pixeln in eine
- Richtung (HORIZONTAL/VERTICAL) gescrollt, wobei die Maus automatisch versteckt
- wird. delta gibt dabei die Anzahl Pixel an (auch negative Werte sind möglich,
- und zwar für aufwärts und links !).
- Verschiedenste Sonderfälle wie das Scrollen um ganze Seiten, aus dem Bildschirm
- herausragende Fenster, nicht oben liegende Fenster u. ä. werden hierbei
- berücksichtigt; ggf. wird die Rechteckliste berücksichtigt.
-
-
- GLOBAL void arrow_window ( WINDOWP window, int arrow, int amount)
-
- Ein Fenster reagiert auf das Anklicken eines Pfeils oder eines Sliders usw.
- arrow ist ein aus AES.H entnommenes Flag:
- WA_UPPAGE Seite nach oben,
- WA_DNPAGE Seite nach unten,
- WA_UPLINE Zeile nach oben,
- WA_DNLINE Zeile nach unten,
- WA_LFPAGE Seite nach links,
- WA_RTPAGE Seite nach rechts,
- WA_LFLINE Zeile nach links,
- WA_RTLINE Zeile nach rechts;
- Außerdem wird noch die Anzahl der Einheiten angegeben, um die gescrollt werden
- soll.
- Diese Routine wird vom Window-Manager auch intern aufgerufen, wenn ein
- entsprechendes Event aufgetreten ist.
- Es wird auch überwacht, daß nicht über den Rand hinaus gescrollt werden kann;
- in solch einem Falle wird auch kein Scrolling oder Neuzeichnen ausgelöst.
- Nach Berechnung der neuen Position im Dokument wird die Funktion arrow der
- Fensterstruktur aufgerufen.
- Ein in die Struktur eingeklinkter Objektbaum reagiert automatisch richtig auf
- die Aktion.
-
-
- GLOBAL void h_slider ( WINDOWP window, int new_value )
-
- Ein Fenster reagiert auf das Bewegen des horizontalen Schiebers, wobei der
- zweite Parameter der vom GEM gelieferte neue Wert für den Schieber (0-1000)
- ist. Nach Berechnen des neuen Schieber-Wertes wird wie beim Anklicken eines
- Pfeils reagiert.
-
-
- GLOBAL void v_slider ( WINDOWP window, int new_value )
-
- Ein Fenster reagiert auf das Bewegen des vertikalen Schiebers, wobei der zweite
- Parameter der vom GEM gelieferte neue Wert für den Schieber (0-1000) ist. Nach
- Berechnen des neuen Schieber-Wertes wird wie beim Anklicken eines Pfeils
- reagiert.
-
-
- GLOBAL void set_sliders ( WINDOWP window, int which, int mode)
-
- Die Schieber-Positionen und/oder die Schieber-Größen werden gesetzt. which kann
- dabei die Werte HORIZONTAL, VERTICAL oder die Kombination beider annehmen,
- während mode Position (SLPOS) oder Größe (SLSIZE) oder beides angibt. Ein
- Neuzeichnen der Slider erfolgt nur dann, wenn sich deren Position wirklich
- verändert hat.
-
-
- GLOBAL void snap_window ( WINDOWP window, RECT *new, int mode)
-
- Die Funktion wird nach dem Verschieben oder Vergrößern/Verkleinern von Fenstern
- vom Window-Manager aufgerufen, kann aber im Bedarfsfall auch direkt aufgerufen
- werden. Zunächst wird geprüft, ob der linke Fenster-Rand genau am linken
- Bildschirmrand liegt; ist dies der Fall, wird die x-Position des Fensters auf -
- 1 gesetzt, wodurch der Fenster-Workbereich genau auf x-Position 0 anfängt.
- Weiterhin wird verhindert, daß ein Fenster zu klein wird.
- Ist in der Fensterstruktur eine snap-Funktion eingehängt, wird diese
- aufgerufen, so daß der Programmierer das genaue Einrasten vornehmen kann.
- new ist dabei die neue Position bzw. Größe des Fensters, während mode angibt,
- ob das Fenster bewegt (MOVED) oder in seiner Größe verändert (SIZED) oder
- beides wurde.
- Voraussetzung bei Aufruf dieser Funktion ist, daß das betreffende Fenster
- sichtbar am Bildschirm, d. h. opened ist, da hier intern mit AES-Funktionen
- gearbeitet wird, ein Fenster allerdings erst beim open_window für die AES
- kreiert (wind_create) und damit existent wird ! Ein geschlossenes Fenster hat
- somit kein AES-Handle. Konsequenz: Noch nicht geöffnete Fenster können nur von
- Hand "gesnappt" werden.
-
-
- GLOBAL void full_window ( WINDOWP window )
-
- "Ich weiß, was Sie sagen wollen, und Sie haben Recht...", so die Worte eines
- bekannten Serienhelden. Es ist offensichtlich, was diese Funktion tut: Das
- betreffende Fenster wird auf seine maximale Größe gebracht, wobei sowohl Grow-
- Boxes gezeichnet werden (sofern grow_shrink auf TRUE steht) als auch die snap-
- Funktion aufgerufen wird.
-
-
- GLOBAL void size_window ( WINDOWP window, const RECT *new)
-
- Das Fenster wird auf eine neue Größe gesetzt; zuvor wird jedoch wiederum die
- snap-Funktion aufgerufen. Die Schieber werden automatisch gesetzt.
-
-
- GLOBAL void move_window ( WINDOWP window, const RECT *new )
-
- Das Fenster wird auf eine neue Position gesetzt; zuvor wird wiederum die snap-
- Funktion aufgerufen. Die Schieber werden wieder automatisch gesetzt.
-
-
- GLOBAL void get_work ( WINDOWP window, BOOLEAN work)
-
- Wurde die Position eines Fensters oder seine Größe verändert, kann mit dieser
- Funktion (sofern es GEM-Force nicht sowieso automatisch tut) der neue Work-
- Bereich errechnet werden (wenn das gleichnamige Flag gesetzt ist). Gleichzeitig
- werden auch die neuen Koordinaten des Scroll-Bereichs berechnet.
- In jedem Fall werden die Koordinaten eines eingehängten Objekt-Baums neu
- berechnet, d. h. einer neuen Position angepaßt.
- Voraussetzung ist auch hier wieder, daß das Fenster für die AES existent,
- nämlich geöffnet, ist.
-
-
- GLOBAL void get_border ( WINDOWP window, int obj, RECT *border )
-
- Diese Funktion errechnet ein Rechteck, das ein Objekt umschließt, das sich in
- dem in eine Fenster-Struktur eingehängten Objekt befindet, sofern das
- dazugehörige Fenster geöffnet ist. Zu kompliziert !? Na gut, ein Beispiel: In
- einem geöffneten Fenster ist ein Objekt eingehängt (z. B. ein Dialog). In dem
- Dialog befindet sich ein Text-Objekt, von dem Sie gerne die Umrisse
- einschließlich Rand und Schatten (!) wissen wollen (z. B. um eine Dragbox zu
- zeichnen). Sie übergeben also den Fensterpointer, den Index des Textobjektes
- innerhalb des Objektbaums und einen Zeiger auf ein Rechteck. Fertig. (Ich gebe
- es ja zu: Die erste Erklärung war zwar kurz, aber etwas unverständlich...)
-
-
- GLOBAL void lock_all ( WINDOWP wp )
-
- Wenn alle Fenster gelockt werden sollen (gelockt heißt, daß sie zwar noch nach
- unten gebracht aber nicht mehr getoppt werden können), sollten Sie diese
- Funktion benutzen. Geben Sie statt einem NULL-Zeiger einem Fenster-Zeiger mit,
- wird dieses Fenster vor dem Locken ausgeschlossen. Dies ist z. B. bei der
- Programmierung modaler Dialoge in Fenstern interessant.
-
-
- GLOBAL void unlock_all ( void )
-
- Gelockte Fenster werden von dieser Routine wieder in den "Normal-Zustand"
- gebracht.
-
-
- GLOBAL void draw_object ( WINDOWP window, int obj )
-
- Eine weitere Funktion für eingehängte Objekte: Sie zeichnet das Objekt
- innerhalb des Fensters, während Rechteckliste und Scroll-Bereich beachtet
- werden.
-
-
- GLOBAL void scroll_area ( const RECT *area, int dir, int delta )
-
- Ein rechteckiger Bildschirmausschnitt wird um eine beliebige Anzahl Pixel in
- eine Richtung gescrollt, der jedoch nicht von der aktuellen Fenstergröße
- abhängig ist. dir gibt die Richtung an (HORIZONTAL, VERTICAL), während delta
- die Anzahl Pixel beinhaltet (negative Werte: abhängig von der Richtung nach
- links bzw. abwärts scrollen). Im Gegensatz zu scroll_window muß nicht der
- gesamte Fensterinhalt gescrollt werden.
-
-
- GLOBAL void clr_area ( const RECT *area )
-
- Ein Bildschirmausschnitt wird gelöscht, d. h. mit weiß gefüllt.
-
-
- GLOBAL void clr_work ( WINDOWP window )
- GLOBAL void clr_scroll ( WINDOWP window )
- GLOBAL void clr_left ( WINDOWP window )
- GLOBAL void clr_top ( WINDOWP window )
- GLOBAL void clr_right ( WINDOWP window )
- GLOBAL void clr_bottom ( WINDOWP window )
-
- Die verschiedenen Bereiche eines Fensters werden gelöscht, wobei clr_left,
- clr_right, clr_top und clr_bottom sich auf die Fensterränder beziehen.
-
-
- GLOBAL void set_redraw ( WINDOWP window, const RECT *area )
-
- Eine Redraw-Meldung für einen bestimmten Bereich eines Fensters wird ausgelöst.
- Dies ist der sauberste Weg, einen Fensterbereich neu zeichnen zu lassen.
-
-
- GLOBAL WINDOWP create_textwindow ( char *array, int doc_w, int doc_h, int kind,
- RECT *border )
-
- Der GEM-Force-Window-Manager erleichtert zweifellos die Fensterverwaltung
- erheblich. Trotzdem mag es unnütz erscheinen, eine Standard-Fensteranwendung
- wie die Anzeige von Text in einem Fenster selbst zu programmieren. Aus diesem
- Grund wurde obige Funktion geschaffen. Sie erzeugt ein Textfenster und stellt
- (für den Programmierer unsichtbar) entsprechende Funktionen für die Verwaltung
- von Textfenstern zur Verfügung, indem diese in die Fenster-Struktur eingehängt
- werden.
- Übergeben als erster Parameter wird ein char-Zeiger auf ein Array, in dem der
- Text zu finden ist, der angezeigt werden soll (meist werden Sie ein 2-
- dimensionales char-Array haben; in diesem Fall reicht ein einfacher Cast auf
- einen einfachen char-Pointer).
- Die nächsten beiden Einträge geben die Größe des Dokuments an, d. h. die
- maximale Anzahl Spalten und Zeilen. Bei char array [100][81] wären das 80 und
- 100, da ja ein Null-Byte am Zeilenende abgerechnet werden muß.
- Der nächste Parameter legt wie üblich die Art des Fensters fest. Die Klasse
- wird automatisch auf CL_TEXT gesetzt.
- Zum Schluß muß noch die Größe des Fensters (außen, nicht der Work-Bereich !)
- übergeben werden, die es beim Öffnen haben soll. Fertig ! Den Rest erledigt
- GEM-Force (siehe handle_window_events).
-
-
- GLOBAL WINDOWP search_window ( int class, int mode )
-
- Es folgen einige nützliche Funktionen für die Abfrage von Fensterattributen
- sowie das Finden von Fenstern.
- Der erste Kandidat sucht ein Fenster einer bestimmten Klasse, wobei mode
- angibt, ob nur offene, geschlossene Fenster oder beide gesucht werden sollen
- (SRCH_CLOSED, SRCH_OPENED, SRCH_ANY).
- Wurde kein passendes Fenster gefunden, wird ein NULL-Zeiger zurückgegeben.
-
-
- GLOBAL WINDOWP find_window ( int handle )
-
- Wenn Sie eine GEM-Fensternachricht bekommen haben und diese selbst auswerten
- wollen, müssen Sie zum mitgelieferten GEM-Handle wissen, welches GEM-Force-
- Fenster zu diesem Handle gehört. Dazu übergeben Sie obiger Funktion das GEM-
- Handle und bekommen den entsprechenden Window-Zeiger oder im Fehlerfall einen
- NULL-Zeiger zurückgeliefert.
-
-
- GLOBAL WINDOWP find_xy_window ( const int x, const int y )
-
- Bei der Fensterverwaltung kann es vorkommen, daß Sie ein Fenster suchen, das
- sich an einer bestimmten x- und y-Position befindet (z. B. bei einem erfolgten
- Mausklick). Dies erledigt diese Routine für Sie, wenn Sie die Koordinaten
- übergeben. Falls kein passendes GEM-Force-Fenster gefunden wurde, wird wieder
- ein NULL-Zeiger zurückgeliefert.
-
-
- GLOBAL WINDOWP find_top ( void )
-
- Einen Zeiger auf das oberste Fenster können Sie mit dieser Funktion ermitteln.
-
-
- GLOBAL BOOLEAN is_top ( WINDOWP window )
-
- Wie offensichtlich sein dürfte, kann mit dieser Routine abgefragt werden, ob
- ein Fenster das oberste ist.
-
-
- GLOBAL BOOLEAN any_open ( BOOLEAN incl_closer )
-
- Es kann getestet werden, ob irgendwelche Fenster offen sind, wobei noch
- spezifiziert werden kann, ob nur Fenster gesucht werden sollen, die auch eine
- Schließbox haben (TRUE). Sonst werden alle Fenster bei der Suche
- berücksichtigt.
-
-
- GLOBAL int num_windows ( int class, int mode, WINDOWP winds[] )
-
- Die Anzahl der Fenster einer oder aller Klassen (class = NIL) kann ermittelt
- werden. Dabei kann noch angegeben werden, ob offene oder geschlossene Fenster
- oder beide berücksichtigt werden sollen (mode SRCH_CLOSED, SRCH_OPENED,
- SRCH_ANY).
- Wird ein Zeiger auf ein Array für Window-Zeiger übergeben, werden alle
- gefundenen Fensterzeiger hier eingetragen, so daß z. B. mit allen gefundenen
- Fenstern bestimmte Aktionen durchgeführt werden können. Andernfalls ist hier
- ein NULL-Zeiger zu übergeben.
-
-
- GLOBAL int num_locked ( void )
-
- Diese Funktion zählt die Fenster, deren Flags WI_LOCKED enthalten. (Zur
- Erinnerung: ein gelocktes Fenster kann zwar nach unten gebracht, nicht aber
- wieder getoppt werden.)
-
-
- 6. Modul TOS
- ============
-
- Dieses Modul stellt ein paar nützliche Funktionen zur Verfügung. Einige dieser
- Funktionen sind zwar in einer GEM-Library etwas fehl am Platze, jedoch kann der
- ein oder andere sie vielleicht sinnvoll in TOS-Programmen einsetzen. Soll
- dieses Modul von GEM-Force genutzt werden, ist die Header-Datei "GF_TOS.H" zu
- importieren.
-
-
- GLOBAL BOOLEAN copy ( const char *quelle, const char *ziel )
-
- Es ist immer wieder nützlich, wenn man Dateien kopieren kann. Das erledigt
- diese Funktion für Sie. Die Quelle darf auch Wildcards enthalten; in diesem
- Falle wird vom Ziel nur der Pfad beachtet. Andernfalls muß die Zieldatei ein
- vollständiger Dateiname sein.
- In jedem Fall wird bis auf einen kleinen Rest der gesamte verfügbare
- Hauptspeicher per malloc reserviert und über diesen Puffer munter kopiert.
- Anschließend wird der Speicherplatz natürlich wieder freigegeben.
-
-
- GLOBAL BOOLEAN test_printer ( void )
-
- Vor dem Drucken sollte man prüfen, ob der Drucker tatsächlich bereit dazu ist,
- weil sonst Probleme "vorprogrammiert" sind; diese kleine Routine gibt TRUE
- zurück wenn, der Drukker bereit ist, FALSE sonst.
-
-
- GLOBAL BOOLEAN file_exist ( const char *filename )
-
- Es wird geprüft, ob eine bestimmte Datei existiert.
-
-
- GLOBAL BOOLEAN path_exist ( const char *pathname )
-
- Es wird geprüft, ob ein bestimmter Pfad existiert.
-
-
- GLOBAL void lprint ( char *string, BOOLEAN convert )
-
- Eine Zeichenkette wird an den Drucker gesendet; anschließend wird ein CR/LF
- ausgelöst. Der zweite Parameter steuert dabei, ob deutsche Umlaute bereits
- richtig gedruckt werden sollen, was beim Drucken von Text sehr hilfreich ist.
- Wird FALSE übergeben, erfolgt keine Konvertierung.
-
-
- GLOBAL void supervisor ( BOOLEAN mode )
-
- Muß einmal betriebssystemnah programmiert werden, muß öfter zwischen
- Supervisor-Mode und dem normalen Modus umgeschaltet werden. Wird TRUE
- übergeben, wird der Supervisor-Mode angeschaltet, sonst wird er ausgeschaltet.
- Wichtig ist, daß nicht "von Hand", d. h. ohne diese Funktion, eingeschaltet und
- dann mit der Funktion ausgeschaltet werden darf (und umgekehrt), da sich die
- Routine beim Einschalten statisch die alte Stack-Adresse merkt und diese beim
- Ausschalten wieder verwendet.
-
-
- GLOBAL void poke ( long adr, char wert )
- GLOBAL void wpoke ( long adr, int wert )
- GLOBAL void lpoke ( long adr, long wert )
- GLOBAL char peek ( long adr )
- GLOBAL int wpeek ( long adr )
- GLOBAL long lpeek ( long adr )
-
- Wer schon einmal mit BASIC programmiert hat, wird diese Funktionen kennen: poke
- schreibt einen Wert an eine Speicheradresse (wpoke ein Wort, lpoke ein
- Langwort). peek dagegen liest den Inhalt einer Speicheradresse aus und gibt den
- Wert mit entsprechendem Typ zurück.
-
-
- GLOBAL void cls ( void )
-
- Nun folgen waschechte TOS-Funktionen: Bei der ersten wird der Bildschirm
- gelöscht und der Cursor in der linken oberen Ecke des Bildschirms positioniert.
-
-
- GLOBAL void cursor_on ( void )
- GLOBAL void cursor_off ( void )
-
- Der Cursor wird an-/ausgeschaltet.
-
-
- GLOBAL void at ( int zeile, int spalte )
-
- Der Cursor wird an eine bestimmte Stelle auf dem Bildschirm gesetzt.
-
-
- GLOBAL void print_at ( int zeile, int spalte, const char *text )
-
- Ein Text wird an einer bestimmten Position auf dem Bildschirm ausgegeben.
- Anschließend erfolgt automatisch ein Zeilenvorschub.
-
-
- GLOBAL void tab ( int spalte )
-
- Der Cursor wird in der aktuellen Zeile in eine bestimmte Spalte gesetzt.
-
-
- GLOBAL void print_tab ( int spalte, const char *text )
-
- Ein Text wird an einer bestimmten Position in der aktuellen Zeile auf dem
- Bildschirm ausgegeben. Anschließend erfolgt automatisch ein Zeilenvorschub.
-
-